home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / infodata / callbook.tar / callbook_1.3 / MAIL_SERVER < prev    next >
Text File  |  1990-02-08  |  13KB  |  379 lines

  1. Article 1460 of alt.sources:
  2. Path: sunybcs!boulder!hellgate.utah.edu!cs.utexas.edu!samsung!rex!uflorida!novavax!twwells!bill
  3. From: bill@twwells.com (T. William Wells)
  4. Newsgroups: alt.sources
  5. Subject: A simple e-mail response server
  6. Message-ID: <1990Feb8.085909.12393@twwells.com>
  7. Date: 8 Feb 90 08:59:09 GMT
  8. Distribution: alt
  9. Organization: None, Ft. Lauderdale, FL
  10. Lines: 365
  11.  
  12. I just finished rewriting and documenting my archive server code
  13. and have decided to make it generally available.
  14.  
  15. This server is *simple*. It is so simple that the documentation
  16. is over twice as large as the server!
  17.  
  18. On the other hand, if all you need is a simple way to make your
  19. files available to others via e-mail, this is a much better deal
  20. than trying to wade through either the decwrl or netlib servers.
  21.  
  22. BTW, if you do find that this server is too simple for your
  23. tastes, I do have the other servers on my system. Send `help' to
  24. comp-archives-server@twwells.com to find out how to get it.
  25.  
  26. echo x - README
  27. sed 's/^X//' >README <<'*-*-END-of-README-*-*'
  28. X             The KISS server v1.0
  29. X            (As in: Keep It Simple, Stupid!)
  30. X
  31. XINTRODUCTION
  32. X
  33. XThis code implements a simple mail-response server and is public domain.  It
  34. Xis designed for a UNIX system; at any rate, it depends on the Bourne shell
  35. Xand a number of UNIX utilities.
  36. X
  37. XThough I may provide fixes and help, I make no promises or guarantees of any
  38. Xkind. However, I'm always interested in input so feel free to let me know your
  39. Xexperiences with this code.
  40. X
  41. XTo use it, you have to have some way of getting mail messages to the server.
  42. XOne way is for your mail system to run the server on receipt of a message.
  43. XAlternately, you can have the messages stored in a mailbox and have cron
  44. Xstart a job to interpret the mailbox for you. As a last resort, you could put
  45. Xsomething in your .profile to run the server every time you log on.  :-)
  46. X
  47. XWhen the server is given a message, it interprets it to determine what is
  48. Xwanted and where to send it. Each request in the message is passed to a
  49. Xprogram you supply, the "service program". The service program is typically a
  50. Xshell script; you get to write it.  A simple example is provided later.
  51. XThere is nothing preventing you from having more than one server address and
  52. Xmultiple service programs; I do this.
  53. X
  54. XEach request in a message results in one mail message being returned to the
  55. Xrequestor; there is no batching. Nor is there any kind of quota or scheduling.
  56. X
  57. XSERVER COMMANDS
  58. X
  59. XThe server recognizes five commands. They are:
  60. X
  61. Xpath <path>     This lets the requestor override the address that would
  62. X        normally be extracted from the header.
  63. X
  64. Xhelp            This is equivalent to the command `send help'.
  65. X
  66. Xindex           This is equivalent to the command `send index'.
  67. X
  68. Xsend <whatever> The whatever is passed to the service program; thus its
  69. X        interpretation is entirely up to you.
  70. X
  71. Xquit            Nothing past this point is interpreted. This is provided so
  72. X        that the occasional lost soul whose signature contains a line
  73. X        that looks like a command can still use the server without
  74. X        getting a bogus response.
  75. X
  76. XThe server interpets the subject line of the message.
  77. X
  78. XThe server translates the characters (` ' " \) (excluding the parentheses) to
  79. Xspaces before processing the message (this is just to simplify writing the
  80. Xshell scripts; it would be a real pain to properly deal with the quoting
  81. Xcharacters in a shell script).
  82. X
  83. XThe server considers a # as the start of a comment; everything from one to the
  84. Xend of its line is ignored.
  85. X
  86. XIf there are no requests in the message, the server responds as if the
  87. Xmessage had a help request in it.
  88. X
  89. XSend commands that are rejected by the service program are returned to the
  90. Xrequestor in a separate message.
  91. X
  92. XIn deciding where to send the responses, the server considers the path
  93. Xcommand and the Reply-To:, From:, and From_ header lines, in that order.  It
  94. Xstops when it finds one of those and uses the address on that line.  Header
  95. Xcontinuation lines are ignored.
  96. X
  97. XINSTALLATION
  98. X
  99. XWarning: I never followed these instructions since my copy of the server got
  100. Xinstalled as I wrote it. This should work but I make no guarantees.
  101. X
  102. X    1) Put the server script wherever you want it run from.
  103. X
  104. XI have a special account for the mail system, so I've put it in the bin for
  105. Xthat account: /home/mail/bin/server.
  106. X
  107. X    2) Write and install the mailrc to be used when sending server mail.
  108. X
  109. XWhether this step is necessary or not depends on the mailer you are using.
  110. XWith mine, mailx, I want it to wait for the delivery agent to finish so that
  111. Xthe server won't be running zillions of processes all at the same time.
  112. XAccordingly, my mailrc contains one line: `set sendwait'.  I put this in the
  113. Xlib directory of my mail account, /home/mail/lib/server.mailrc.
  114. X
  115. X    3) Edit the assignments at the top of the server script.
  116. X
  117. XThere are four defines you might want to change.
  118. X
  119. X    ADMIN is a mail address to send problem reports to. There aren't a lot of
  120. X        possible problems, but this lets the server have some chance to
  121. X        report them. I send them off to the `mail' account.
  122. X
  123. X    MAILRC is the file you installed in the previous step. If you didn't
  124. X        create one, make this /dev/null.
  125. X
  126. X    MAIL is the name of the program to deliver mail. It needs to have a -s
  127. X        option to specify the subject and to read the body of the message
  128. X        from standard in.
  129. X
  130. X    LOG is the name of a log file to write information about server requests
  131. X        to. If you don't want logging, set it to /dev/null. If you do want
  132. X        logging, you have to do two other things. First, you have to
  133. X        create the log file with permissions permitting world write and
  134. X        you have to arrange to truncate the log file periodically.
  135. X
  136. X    4) Create a service program.
  137. X
  138. XThe server itself doesn't know beans about how to get to your archived data.
  139. XSo you have to write a program to do this.  The first argument to the program
  140. Xis the archive name passed to the server script; the remaining arguments are
  141. Xthe arguments to the send command.
  142. X
  143. XYour program should do two things: verify that the request is valid and then
  144. Xgenerate the text that is to be returned as the response to the request.
  145. X
  146. XIf the request is invalid, your program should exit with a non zero exit code.
  147. XIf it is valid, your program should exit with a sero exit code after having
  148. Xprinted the text to standard output. Once you've created the program, you
  149. Xshould put it somewhere convenient; since I have a separate account for
  150. Xcomp.archives, I put the program in its bin, as /home/comparc/bin/dbsend.
  151. X
  152. XI expect that most service programs will be a shell script; that is what I use
  153. Xfor comp.archives. Here is a script (not the one I use) that will suffice for
  154. Xan archive where everything is contained in one directory. You should read the
  155. Xcomments for hints in writing your own code:
  156. X
  157. X    # Fail if more than one name in the send request.
  158. X
  159. X    if [ $# -ne 2 ]; then
  160. X        exit 1
  161. X    fi
  162. X
  163. X    # Fail if there is a .. in the name. This takes care of attempts like:
  164. X    # `send ../../../../../../../../etc/passwd'.
  165. X
  166. X    # Note the quotes around each reference to $2. Think about what would
  167. X    # happen with file name expansion and a `send *'....
  168. X
  169. X    if expr "$2" : '.*\.\.' >/dev/null; then
  170. X        exit 1
  171. X    fi
  172. X
  173. X    # Put us in the proper directory.
  174. X
  175. X    cd /usr/archive
  176. X
  177. X    # Fail if the file doesn't exist or is empty.
  178. X
  179. X    if [ ! -s "$2" ]; then
  180. X        exit 1
  181. X    fi
  182. X
  183. X    # Print the file.
  184. X
  185. X    cat "$2"
  186. X
  187. X    # Done, request satisfied.
  188. X
  189. X    exit 0
  190. X
  191. X    5) Set up your index and help responses.
  192. X
  193. XYour server should always respond to `send help' and `send index' commands.
  194. X
  195. XNote that the sample script doesn't explicitly deal with these commands; the
  196. Xpresumption is that there are files `help' and `index' in the directory.
  197. X
  198. X    5) Connect the server to the mail system.
  199. X
  200. XIf your system has the ability to run a program in response to mail to an
  201. Xaddress, all you have to do is to set up the mail alias to run the server
  202. Xscript. You must run the server script with two arguments.  The first
  203. Xargument is the name of the server. I just use the server alias. The second
  204. Xis the path for the service script. You should use an absolute path name.
  205. X
  206. XIf you have a system which won't do this, all is not lost. You'll can write a
  207. Xshort script and run it from cron. What you do is have the mail system store
  208. Xthe messages in a mailbox somewhere and process them later. At one time, I
  209. Xhad a script vaguely like:
  210. X
  211. X    MAILRC=/dev/null ; export MAILRC
  212. X    while [ -s /usr/mail/comparcd ]; do
  213. X        /usr/bin/mail -n -N -f /usr/mail/comparcd <<\+
  214. X        pipe "/home/mail/bin/server comp-archives-server \
  215. X             /home/comparc/bin/dbsend"
  216. X        q
  217. X        +
  218. X    done
  219. X
  220. Xand I ran it once an hour.  This is gross and ugly but it can be made to work.
  221. X
  222. X    7) Test it out!
  223. X
  224. XOnce you've gone through the installation, you should send a message to the
  225. Xserver and see what it does. With any luck you'll get a response back.
  226. X
  227. X---
  228. XBill                    { uunet | novavax | ankh } !twwells!bill
  229. Xbill@twwells.com
  230. *-*-END-of-README-*-*
  231. echo x - Makefile
  232. sed 's/^X//' >Makefile <<'*-*-END-of-Makefile-*-*'
  233. X# Well, I don't really need a makefile for a shell script, but this does make
  234. X# building the shar more reliable.
  235. X
  236. Xserver.shar : README Makefile server
  237. X    shar README Makefile server >$@
  238. X
  239. Xclean :
  240. X    rm server.shar
  241. *-*-END-of-Makefile-*-*
  242. echo x - server
  243. sed 's/^X//' >server <<'*-*-END-of-server-*-*'
  244. X# The KISS server. v1.0
  245. X
  246. X# You might want to change these...see the README for an explanation.
  247. X
  248. XADMIN=mail
  249. XMAILRC=/home/mail/lib/server.mailrc ; export MAILRC
  250. XMAIL=/usr/bin/mail
  251. XLOG=/home/mail/logs/archive.log
  252. X
  253. X# Set up variables we'll use.
  254. X
  255. XT=/tmp/serv$$
  256. XARC="$1"
  257. XCMD="$2"
  258. X
  259. X# This'll zap any temp files created.
  260. X
  261. Xtrap "rm -f $T.[a-z]; exit 0" 0 1 2 3 15
  262. X
  263. X# If the archive name was not specified or if the server shell does not
  264. X# exist, complain.
  265. X
  266. Xif [ $# -lt 2 -o ! -x "$CMD" ]; then
  267. X    $MAIL -s "problem with $0 $*" $ADMIN
  268. X    exit 0
  269. Xfi
  270. X
  271. X# First thing, save the message in a temp file and turn tabs into spaces.
  272. X# Also translate dangerous characters into something harmless.
  273. X
  274. Xtr '\011'\''`"\\' '     ' >$T.a
  275. X
  276. X# Construct a file from the message, suitable for running through the shell
  277. X# to extract relevant info. The address parameters are changed into shell
  278. X# variable assignments; the send requests are turned into echos.
  279. X
  280. Xsed -n \
  281. X's/#.*//
  282. Xs/  */ /g
  283. Xs/ $//
  284. X1,/^$/{
  285. X    s/([^)]*)//g
  286. X    /^From /s/^From \([^ ]*\).*/env='\''\1'\''/p
  287. X    /^From: /s/^From: \(.*\)/from='\''\1'\''/p
  288. X    /^Reply-To: /s/^Reply-To: \(.*\)/reply='\''\1'\''/p
  289. X    /^Subject: /!d
  290. X    s/^Subject: //
  291. X}
  292. Xs/^ //
  293. X/^path /s/^path \([^ ]*\).*/path='\''\1'\''/p
  294. X/^index$/s/.*/echo '\''"index"'\''/p
  295. X/^help$/s/.*/echo '\''"help"'\''/p
  296. X/^send /{
  297. X    s/^send //
  298. X    s/ /"'\'' '\''"/g
  299. X    s/$/"'\''/
  300. X    s/^/echo '\''"/p
  301. X}
  302. X/^quit$/q' <$T.a >$T.b
  303. X
  304. X# Next, run the file by the shell. The addresses are captured from the
  305. X# assignments; the commands get redirected to a temp file
  306. X
  307. Xenv=''
  308. Xfrom=''
  309. Xreply=''
  310. Xpath=''
  311. Xaddr=''
  312. X
  313. X. $T.b >$T.c
  314. X
  315. X# Determine the address to send to.
  316. X
  317. Xif   [ -n "$path"  ]; then addr="$path"
  318. Xelif [ -n "$reply" ]; then addr="$reply"
  319. Xelif [ -n "$from"  ]; then addr="$from"
  320. Xelif [ -n "$env"   ]; then addr="$env"
  321. Xfi
  322. X
  323. X# If the address contains <stuff>, make 'stuff' the address.
  324. X
  325. Xbaddr=`expr "$addr" : '.*<\([^>]*\)>.*'`
  326. Xif [ -n "$baddr" ]; then
  327. X    addr="$baddr"
  328. Xfi
  329. X
  330. X# No address means there is a problem.
  331. X
  332. Xif [ -z "$addr" ]; then
  333. X    $MAIL -s "message with no address sent to $ARC" $ADMIN <$T.a
  334. X    rm -f $T.[a-z]
  335. X    exit 0
  336. Xfi
  337. X
  338. X# Turn empty requests into a help request.
  339. X
  340. Xif [ ! -s $T.c ]; then
  341. X    echo '"help"' >$T.c
  342. Xfi
  343. X
  344. X# Sort and uniq the commands to run. We don't do this when capturing the
  345. X# commands, since putting the . command into a pipe doesn't do what we want.
  346. X# Then run a command and return its standard output to the requester. If the
  347. X# command returns failure, save the command arguments in a file.
  348. X
  349. X>$T.e
  350. Xsort -u $T.c \
  351. X    | while read args; do
  352. X    eval set -- $args
  353. X    if $CMD $ARC "$@" >$T.d; then
  354. X        $MAIL -s "Reply from $ARC re: send $*" "$addr" <$T.d
  355. X        echo sent "$addr" $ARC $CMD "$@" >>$LOG
  356. X    else
  357. X        echo "$@" >>$T.e
  358. X        echo fail "$addr" $ARC $CMD "$@" >>$LOG
  359. X    fi
  360. Xdone
  361. X
  362. X# If any commands failed, make a special return to the sender.
  363. X
  364. Xif [ -s $T.e ]; then
  365. X    {
  366. X        echo "The following requests could not be honored. Sorry."
  367. X        echo
  368. X        sed 's/^/        send /' $T.e
  369. X    } | $MAIL -s "Reply from $ARC re: invalid requests" "$addr"
  370. Xfi
  371. X
  372. X# We're done.
  373. X
  374. Xexit 0
  375. *-*-END-of-server-*-*
  376. exit
  377.  
  378.  
  379.